package com.java.code.insu;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.cfg.BaseSettings;
import com.java.code.utils.date.DateUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 两定接口请求
 *
 * @author weichuanyuan
 * @e-mail wei.cy@bsoft.com.cn
 * @date 2021/11/28 17:24
 * @package com.java.code.insu
 * @description
 */
public class AliCsbInsu {

    public final static String _api_name_pre = "hsa-fsi-";
    public final static String _api_name_1101 = "1101";

    public final static String _api_name_5201 = "5201";
    public final static String _api_name_5206 = "5206";
    public final static String url = "http://10.77.211.236:80/";
    public final static String _api_version = "1.0.0";
    //正式库
    public final static String _api_access_key = "b48b8b46b4aa44ccad9fb49387d5122c";
    public final static String secretKey = "3APNcFo/4CiDeiOEDEyXjLINRVY=";

    //    public final static String url = "http://10.77.224.18:9001/";
//    public final static String _api_version = "1.0.0";
//    //B中心
//    public final static String _api_access_key = "f36c65fdce974ff78a34f42dcd8009da";
//    public final static String secretKey = "drpcHvKLw19Rsb2Lv6gALGn6bmE=";
    String name = "{\"infno\":\"1101\",\"msgid\":\"H4404030007120210802104501\",\"mdtrtarea_admvs\":\"360301\",\"insuplc_admdvs\":\"360301\",\"recer_sys_code\":\"360301\",\"dev_no\":\"\",\"dev_safe_info\":\"\",\"cainfo\":\"\",\"signtype\":\"SM3\",\"infver\":\"V1.0\",\"opter_type\":\"1\",\"opter\":\"00001\",\"opter_name\":\"系统管理员\",\"inf_time\":\"2021-08-02 10:49:25\",\"fixmedins_code\":\"H36030200054\",\"fixmedins_name\":\"测试医院\",\"sign_no\":\"\",\"input\":{\"data\":{\"mdtrt_cert_type\":\"02\",\"mdtrt_cert_no\":\"360301198501010401\",\"card_sn\":\"\",\"begntime\":\"\",\"psn_cert_type\":\"\",\"certno\":\"\",\"psn_name\":\"\"}}}";

    public final static Map<String, String> cumMap = new HashMap() {
        {
            put("D310101", "职工统筹基金年度累计");
            put("D390101", "居民统筹基金年度累计");
            put("D330101", "职工大额补助基金年度累计");
            put("D390301", "居民大病保险基金年度累计");
            put("D320101_POLGB04", "公务员额外段年度基金累计");
            put("D610101", "医疗救助基金年度累计");
            put("D610102", "医疗救助基金(重特大疾病)年度累计");
            put("D999998", "现金支出累计");
            put("TQ390301", "居民大病起付标准年度累计");
            put("TS390301", "居民大病合规费用年度累计");
            put("L0000_BIZ21_INS310", "职工普通住院年度起付次数累计");
            put("Z0000", "全业务个人负担累计");
            put("F0000", "全业务总费用");
            put("D320101_CG", "公务员常规段年度基金累计");
            put("Z999973", "职工医疗保险二次补偿申报费累计");
            put("D640101", "财政兜底基金");
            put("D340101", "离休医疗保障基金累计");
            put("D390101_TRE110", "居民统筹基金门诊年度累计");
            put("D620101", "美国微笑列车基金累计");
            put("D99999601", "医院垫付基金累计");
            put("C0000_TRE990101001", "尿毒症免费血透次数");
            put("C0000_TRE990101002", "重性精神病门诊年度次数累计");
            put("D320101TRE14M004", "居民精神病门诊累计");
            put("D390101_TRE9901001", "居民门诊两病高血压年度统筹基金累计");
            put("D390101_TRE9901002", "居民门诊两病糖尿病年度统筹基金累计");
            put("D310101_TR141", "职工二类门特年度累计");
            put("D390101_TR141", "居民二类门特年度累计");
            put("TQ610101", "医疗救助起付标准年度累计");
            put("D350101", "一至六级伤残军人补助基金累计");
            put("D999998BIZ2104", "军转干人员专项补助涉及的大病个人自付费用");
            put("D310401", "军转干基金年度累计");
            put("D310101_BIZ51_ILL9902_PRDB[生育登记号]", "职工生育门诊产前检查统筹基金孕次累计");
            put("D330101_BIZ51_ILL9902_PRDB[生育登记号]", "职工生育门诊产前检查大病基金孕次累计");
            put("D610101_BIZ11", "医疗救助基金普通门诊年度累计");
            put("D610101_BIZ110104", "医疗救助基金门诊统筹年度累计");
            put("D610101_BIZ18", "医疗救助基金大病特药年度累计");
            put("D610101_BIZ14", "医疗救助基金一类门特年度累计");
            put("D610101_BIZ21", "医疗救助基金普通住院年度累计");
            put("L0000_BIZ21_INS310", "职工普通住院年度次数累计");
            put("L0000_BIZ21_INS390", "居民普通住院年度次数累计");
            put("D390301_TR142", "居民二类门特大病基金年度累计");
            put("D330101_TR142", "职工二类门特大病基金年度累计");
        }
    };

    /**
     * 患者信息查询
     *
     * @throws Exception
     */
    @Test
    public void test_1101() throws Exception {
        RootName rootName = getRootName();
        rootName.setInfno(_api_name_1101);
        rootName.setMdtrtareaAdmvs("360829");
        rootName.setInsuplcAdmdvs("");

        Data data = new Data();
        data.setBegntime("2021-11-27 14:02:04");
        data.setCardSn("360900D15600000551417810F0CE94FB");
        data.setCertno("362201195104070040");
        data.setMdtrtCertNo("514178105");
        data.setMdtrtCertType("03");
        data.setPsnCertType("01");
        data.setPsnName("易斌员");

        Input input = new Input();
        input.setData(data);
        rootName.setInput(input);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String body = mapper.writeValueAsString(rootName);
        System.out.println(body);

        HttpEntity httpEntity = revoke(_api_name_pre + _api_name_1101, body);
        if (null == httpEntity) {
            System.out.println("调用失败！");
        } else {
            System.out.println(EntityUtils.toString(httpEntity, "UTF-8"));
        }
    }

    /**
     * 就诊信息查询
     *
     * @throws Exception
     */
    @Test
    public void test_5201() throws Exception {
        RootName rootName = getRootName();
        rootName.setFixmedinsCode("H36098302558");
        rootName.setFixmedinsName("高安市骨伤医院");
        rootName.setInfno(_api_name_5201);
        rootName.setMdtrtareaAdmvs("360983");
        //rootName.setInsuplcAdmdvs("360983");

        String now = DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN);

        Data data = new Data();
        data.setBegntime("2018-01-01 00:00:00");
        data.setEndtime(now);
        data.setMedType("21");
        data.setPsnNo("3609001902000000003949799");

        Input input = new Input();
        input.setData(data);
        rootName.setInput(input);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String body = mapper.writeValueAsString(rootName);
        System.out.println(body);

        HttpEntity httpEntity = revoke(_api_name_pre + _api_name_5201, body);
        if (null == httpEntity) {
            System.out.println("调用失败！");
        } else {
            System.out.println(EntityUtils.toString(httpEntity, "UTF-8"));
        }
    }

    /**
     * 累计项查询
     *
     * @throws Exception
     */
    @Test
    public void test_5206() throws Exception {
        RootName rootName = getRootName();
        rootName.setFixmedinsCode("H36098302558");
        rootName.setFixmedinsName("高安市骨伤医院");
        rootName.setInfno(_api_name_5206);
        rootName.setMdtrtareaAdmvs("360983");
        //rootName.setInsuplcAdmdvs("360983");
        String year = DateUtils.format(new Date(), DateUtils.YEAR);
        Data data = new Data();
        data.setPsnNo("3609001902000000001106837");
        data.setCumYm("");

        Input input = new Input();
        input.setData(data);
        rootName.setInput(input);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String body = mapper.writeValueAsString(rootName);
        System.out.println(body);

        HttpEntity httpEntity = revoke(_api_name_pre + _api_name_5206, body);
        if (null == httpEntity) {
            System.out.println("调用失败！");
        } else {
            String result = EntityUtils.toString(httpEntity, "UTF-8");
            System.out.println(result);
            OutputRoot outputRoot = mapper.readValue(result, OutputRoot.class);
            if (outputRoot != null && outputRoot.getOutput() != null && outputRoot.getOutput().getCuminfo() != null) {
                List<Cuminfo> cuminfos = outputRoot.getOutput().getCuminfo();
                cuminfos.stream().filter(k -> k.getYear().equals(year)).forEach(m -> {
                    if (cumMap.containsKey(m.cumTypeCode)) {
                        System.out.println(cumMap.get(m.cumTypeCode) +
                                "[" + m.cumTypeCode + "]:" + "[" + m.getInsutype() + "]:" +
                                m.getCum());
                    } else {
                        System.out.println("未知" +
                                "[" + m.cumTypeCode + "]:" + "[" + m.getInsutype() + "]:" +
                                m.getCum());
                    }
                });
            }
        }
    }


    private HttpEntity revoke(String apiName, String body) throws Exception {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httppost = new HttpPost(url + apiName);

        httppost.setHeader("Content-Type", "application/json");
        httppost.setHeader("user-agent", "Apache-HttpClient/4.5.13 (Java/1.8.0_301)");

        httppost.setHeader("_api_access_key", _api_access_key);
        httppost.setHeader("_api_version", _api_version);
        httppost.setHeader("_api_name", apiName);
        int _api_timestamp = DateUtils.secondTimestamp(new Date());
        httppost.setHeader("_api_timestamp", String.valueOf(_api_timestamp));


        String signStr = "_api_access_key=" + _api_access_key + "&_api_name=" + apiName + "&_api_timestamp=" + _api_timestamp + "&_api_version=" + _api_version;
        Mac mac = Mac.getInstance("HmacSHA1");
        Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
        mac.init(sKey);
        byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
        String _api_signature = new BASE64Encoder().encode(hash);

        httppost.setHeader("_api_signature", _api_signature);

        //设置body
        httppost.setEntity(new StringEntity(body, Charset.forName("UTF-8")));

        //使用httpclient进行连接
        CloseableHttpResponse response = client.execute(httppost);

        //查询成功
        String content = "";
        if (response.getStatusLine().getStatusCode() == 200) {
            return response.getEntity();
        } else {
            System.out.println("返回失败！失败编码：" + String.valueOf(response.getStatusLine().getStatusCode()));
            return null;
        }
    }

    ///////////////////////////////////输入实体///////////////////////////////////
    private RootName getRootName() {
        RootName rootName = new RootName();
        rootName.setMsgid("H36090200113202111270202047315");
        rootName.setRecerSysCode("s1");
        rootName.setDevNo("");
        rootName.setDevSafeInfo("");
        rootName.setCainfo("");
        rootName.setSigntype("SM3");
        rootName.setInfver("V1.0");
        rootName.setOpterType("1");
        rootName.setOpter("1007");
        rootName.setOpterName("王伟");
        String now = DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN);

        rootName.setInfTime(now);
        rootName.setFixmedinsCode("H36090200113");
        rootName.setFixmedinsName("宜春经济开发区金园街道社区卫生服务中心");
        rootName.setSignNo("3706347");

        return rootName;
    }

    @lombok.Data
    @NoArgsConstructor
    public static class RootName {
        private String infno;
        private String msgid;
        @JsonProperty("mdtrtarea_admvs")
        private String mdtrtareaAdmvs;
        @JsonProperty("insuplc_admdvs")
        private String insuplcAdmdvs;
        @JsonProperty("recer_sys_code")
        private String recerSysCode;
        @JsonProperty("dev_no")
        private String devNo;
        @JsonProperty("dev_safe_info")
        private String devSafeInfo;
        private String cainfo;
        private String signtype;
        private String infver;
        @JsonProperty("opter_type")
        private String opterType;
        private String opter;
        @JsonProperty("opter_name")
        private String opterName;
        @JsonProperty("inf_time")
        private String infTime;
        @JsonProperty("fixmedins_code")
        private String fixmedinsCode;
        @JsonProperty("fixmedins_name")
        private String fixmedinsName;
        @JsonProperty("sign_no")
        private String signNo;
        private Input input;
    }

    @lombok.Data
    @NoArgsConstructor
    public static class Data {
        @JsonProperty("mdtrt_cert_type")
        private String mdtrtCertType;
        @JsonProperty("mdtrt_cert_no")
        private String mdtrtCertNo;
        @JsonProperty("card_sn")
        private String cardSn;
        private String begntime;
        @JsonProperty("psn_cert_type")
        private String psnCertType;
        private String certno;
        @JsonProperty("psn_name")
        private String psnName;

        @JsonProperty("psn_no")
        private String psnNo;
        private String endtime;
        @JsonProperty("med_type")
        private String medType;
        @JsonProperty("mdtrt_id")
        private String mdtrtId;
        @JsonProperty("cum_ym")
        private String cumYm;
    }

    @lombok.Data
    @NoArgsConstructor
    public static class Input {
        private Data data;
    }
    ///////////////////////////////////输入实体///////////////////////////////////


    ///////////////////////////////////返回实体///////////////////////////////////
    @lombok.Data
    @NoArgsConstructor
    public static class OutputRoot implements Serializable {
        private Output output;
        private int infcode;
        @JsonProperty("warn_msg")
        private String warnMsg;
        private String cainfo;
        @JsonProperty("err_msg")
        private String errMsg;
        @JsonProperty("refmsg_time")
        private String refmsgTime;
        private String signtype;
        @JsonProperty("respond_time")
        private String respondTime;
        @JsonProperty("inf_refmsgid")
        private String infRefmsgid;
    }

    @lombok.Data
    @NoArgsConstructor
    public static class Cuminfo implements Serializable {
        @JsonProperty("cum_type_code")
        private String cumTypeCode;
        private String year;
        private double cum;
        @JsonProperty("cum_ym")
        private String cumYm;
        private String insutype;
    }

    @lombok.Data
    @NoArgsConstructor
    public static class Output implements Serializable {
        private List<Cuminfo> cuminfo;
    }
    ///////////////////////////////////返回实体///////////////////////////////////


}
